home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 1997 November & December / Amiga-CD 1997 #11-12.iso / pd-disketten / ungepackt / 4_96 / apd-4-96-2 / gut gekurvt / listing.cpp < prev    next >
C/C++ Source or Header  |  1996-03-13  |  3KB  |  109 lines

  1. #include <math.h>
  2. #include <intuition/intuition.h>
  3. #include <pragma/intuition_lib.h>
  4. #include <pragma/exec_lib.h>
  5. #include <pragma/graphics_lib.h>
  6. #include <pragma/dos_lib.h>
  7. #include <math.h>
  8. #include <stream.h>
  9.  
  10. // die erste Version: schön, aber langsam
  11.  
  12. void Bezier1(struct RastPort *rp, double k0x,
  13.   double k0y,double k1x,double k1y,double k2x,
  14.   double k2y,double k3x,double k3y, double range)
  15. {
  16.   // Vereinfachung für n=4; sonst ist die
  17.   const n = 4; //  Parameterübergabe komplizierter
  18.   double bx[n+1][n+1];  // Zählung von 1-n
  19.   double by[n+1][n+1];
  20.   const double step = 1.0/range;
  21.  
  22.   // Parameter in Array
  23.   bx[0][0]=k0x; bx[1][0]=k1x; bx[2][0]=k2x;
  24.   bx[3][0]=k3x; by[0][0]=k0y; by[1][0]=k1y;
  25.   by[2][0]=k2y; by[3][0]=k3y;
  26.  
  27.   Move(rp, (long)k0x, (long)k0y);
  28.   for(double t = step; t <= range*step; t+= step) {
  29.     for(int r=1; r<=n; r++) {
  30.       for(int i=0; i<= n-r; i++) {
  31.         bx[i][r] = (1-t)*bx[i][r-1]+t*bx[i+1][r-1];
  32.         by[i][r] = (1-t)*by[i][r-1]+t*by[i+1][r-1];
  33.       }
  34.     }
  35.     Draw(rp, (long)bx[0][3], (long)by[0][3]); 
  36.   }   
  37. }
  38.  
  39.  
  40. void Bezier2(struct RastPort *rp,double k0x,
  41.   double k0y,double k1x,double k1y,double k2x,
  42.   double k2y,double k3x,double k3y, double range)
  43. {
  44.   double bx, by;
  45.  
  46.   const double step = 1.0/range;
  47.   // Konstante rst zum schnelleren Bearbeiten
  48.   const double rst = range*step;
  49.   
  50.   Move(rp,(long)k0x,(long)k0y);
  51.   for(double t = step; t <= rst; t+= step) 
  52.   {
  53.     bx = (1-t)*(1-t)*((1-t)*k0x + (3*t)*k1x)
  54.          + (t*t)*(3*(1-t)*k2x + t*k3x);
  55.     by = (1-t)*(1-t)*((1-t)*k0y + (3*t)*k1y)
  56.          + (t*t)*(3*(1-t)*k2y + t*k3y);
  57.     Draw(rp,(long)bx,(long)by);
  58.   }
  59. }
  60.  
  61.  
  62. void Bezier3(struct RastPort *rp,double k0x,
  63.   double k0y,double k1x,double k1y,double k2x,
  64.   double k2y,double k3x,double k3y, double range)
  65. {
  66.   // Variablen, die nur einmal berechnet werden:
  67.   double bx, by, emt, emt2, t2, tm3, emtm3;
  68.  
  69.   // improvisierte Abschätzung der Schrittweite:
  70.   const double step = 1.0/range;
  71.   const double rst = range*step;
  72.   Move(rp,(long)k0x,(long)k0y);
  73.   for(double t = step; t <= rst; t+= step) 
  74.   {
  75.     emt = 1-t; emt2 = emt*emt; emtm3 = 3*emt;
  76.     t2 = t*t; tm3 = 3*t;
  77.     bx = emt2*(emt*k0x+tm3*k1x)+t2*(emtm3*k2x+t*k3x);
  78.     by = emt2*(emt*k0y+tm3*k1y)+t2*(emtm3*k2y+t*k3y);
  79.     Draw(rp,(long)bx,(long)by);
  80.   }
  81. }
  82.  
  83. struct Window *win =  OpenWindowTags
  84. ( NULL,
  85.   WA_Flags, WFLG_ACTIVATE | WFLG_CLOSEGADGET |
  86.      WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET,
  87.   WA_Top, 11,             WA_Width, 640,      
  88.   WA_Height, 512,         WA_Left, 0,     
  89.   WA_BlockPen, 4,         WA_DetailPen, 3,
  90.   WA_Title, (char*)"Bézier-Kurven...", TAG_END
  91. );
  92.  
  93. struct RastPort *rp = win->RPort;
  94. #define F(x)    SetAPen(rp,x)
  95.  
  96. void main() 
  97. {
  98.   if(win) { int i;
  99.     F(1); for (i=0; i< 50; i++)
  100.     Bezier1(rp,10,20+i,600,70+i, 20,70+i,600,160+i,80);
  101.     F(2); for (i=0; i< 50; i++)
  102.     Bezier2(rp,10,140+i,600,200+i,20,200+i,600,280+i,80);
  103.     F(3); for (i=0; i< 50; i++)
  104.     Bezier3(rp,10,250+i,600,320+i,20,320+i,600,430+i,80);
  105.     Delay(250);       // 5 Sekunden warten
  106.     CloseWindow(win);   // und schließen
  107.   }
  108. }
  109.